#region copyright
/*
* Copyright (c) 2009, Dion Kurczek
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the <organization> nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY DION KURCZEK ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL DION KURCZEK BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;

namespace SCG.Prism.Server
{
    //PrismRoom represents a single chat room, game, etc.
    //Can be configured to accept a maximum number of guests.
    public class PrismRoom
    {
        //lock
        public object RoomGuestLock = new object();

        //Constructor
        public PrismRoom(string subjectName, string roomName)
        {
            _subjectName = subjectName;
            _roomName = roomName;
        }

        //The subject that the room belongs to
        public string SubjectName
        {
            get
            {
                return _subjectName;
            }
        }

        //The name of the room - set in constructor call
        public string RoomName
        {
            get
            {
                return _roomName;
            }
        }

        //Maximum number of users allowed in the room (0 allows unlimited number)
        public int MaxGuests
        {
            get
            {
                return _maxGuests;
            }
            set
            {
                _maxGuests = value;
            }
        }

        //Determine if the room is "locked" - meaning max number of guests have entered and
        //"activated" the subject (game, etc.)
        public bool Locked
        {
            get
            {
                return _locked;
            }
        }

        //Persistent property determines if the room stays alive after all guests leave
        public bool Persistent
        {
            get
            {
                return _persistent;
            }
            set
            {
                _persistent = value;
            }
        }

        //Access the guests in this room
        public List<PrismGuest> RoomGuests
        {
            get
            {
                return _roomGuests;
            }
        }

        //Add a Guest to room
        public void AddGuest(PrismGuest guest)
        {
            lock (RoomGuestLock)
            {
                RoomGuests.Add(guest);
            }

            //Lock the room if the maximum number of guests has been reached
            if (MaxGuests > 0)
                if (RoomGuests.Count >= MaxGuests)
                {
                    _locked = true;
                    SendToGuests("START");
                }
        }

        //Remove a guest from room        
        public void RemoveGuest(PrismGuest guest)
        {       
            lock (RoomGuestLock)
            {
                RoomGuests.Remove(guest);
            }
        }

        //Send a message to all guests in this room
        public void SendToGuests(params object[] tokens)
        {
            for(int n = RoomGuests.Count - 1; n >= 0; n--)
            {
                try
                {
                    PrismGuest guest = RoomGuests[n];
                    guest.WriteTokens(tokens);
                }
                catch
                {
                }
            }
        }

        //Send to all guests in room, excluding specified guest
        public void SendToGuests(PrismGuest excludeGuest, params object[] tokens)
        {
            for (int n = RoomGuests.Count - 1; n >= 0; n--)
            {
                try
                {
                    PrismGuest guest = RoomGuests[n];
                    if (guest != excludeGuest)
                        guest.WriteTokens(tokens);
                }
                catch
                {
                }
            }
        }

        //Private members
        private string _roomName;
        private List<PrismGuest> _roomGuests = new List<PrismGuest>();
        private string _subjectName;
        private int _maxGuests;
        private bool _locked;
        private bool _persistent;        
    }

    //Event arguments for a PrismRoom
    public class PrismRoomEventArgs : EventArgs
    {
        //Private members
        private PrismRoom _room;

        //Constructor
        public PrismRoomEventArgs(PrismRoom room)
        {
            _room = room;
        }

        //Public property
        public PrismRoom Room
        {
            get
            {
                return _room;
            }
        }
    }
}
